package cn.mayaslight.wechat.springbean;

import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import cn.mayaslight.common.utils.SyncUtils;
import cn.mayaslight.wechat.api.TicketAPI;
import cn.mayaslight.wechat.common.WeChatConsts;
import cn.mayaslight.wechat.exception.TokenIsNullException;
import cn.mayaslight.wechat.exception.TokenUtilsIsNullException;

@Component
public class TicketGetter {

	@Resource
	private RedisTemplate<String, String> redisTemplate;
	@Resource
	private TokenGetter tokenGetter;
	
	private static Object LOCK = new Object();
	
	private static TicketGetter instance = null; 
	
	private TicketGetter() {}
	
	@PostConstruct
	public void init() {
		instance = this;
	}
	
	public static TicketGetter getInstance () {
		instance = SyncUtils.sync(instance, TicketGetter.class, LOCK);
		return instance;
	}

	public String get(String corpid, String secret, boolean isQyHao) {
		if(tokenGetter == null){
			throw new TokenUtilsIsNullException();
		}
		String token = tokenGetter.get(corpid, secret, isQyHao);
		if (StringUtils.isBlank(token))
			throw new TokenIsNullException();
		else {
			String redisKey = WeChatConsts.RedisKeys.RES_JSAPI_TICKET_KEY_PRE + corpid;
			String ticket = redisTemplate.opsForValue().get(redisKey);
			if (!StringUtils.isBlank(ticket)) {
				synchronized (this) {
					ticket = redisTemplate.opsForValue().get(redisKey);
					if (StringUtils.isBlank(ticket)) {
						ticket = TicketAPI.ticket(isQyHao, token).getTicket();
						redisTemplate.opsForValue().set(redisKey, ticket, WeChatConsts.Constants.RES_TOKEN_AND_TICKET_EXPIRE_SECOND, TimeUnit.SECONDS);
					}
				}
			}
			return ticket;
		}
	}

	public RedisTemplate<String, String> getRedisTemplate() {
		return redisTemplate;
	}

	public TicketGetter setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
		this.redisTemplate = redisTemplate;
		return this;
	}

	public TokenGetter getTokenGetter() {
		return tokenGetter;
	}

	public void setTokenGetter(TokenGetter tokenGetter) {
		this.tokenGetter = tokenGetter;
	}

}
